home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / MUser17src.lha / MultiUser / src / Library / Segment.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-07  |  7.7 KB  |  303 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Segment Management                                                        *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/execbase.h>
  12. #include <exec/alerts.h>
  13. #include <dos/dos.h>
  14. #include <dos/dosextens.h>
  15. #include <dos/dostags.h>
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/utility.h>
  19.  
  20. #include "Memory.h"
  21. #include "Segment.h"
  22. #include "Misc.h"
  23. #include "Config.h"
  24. #include "LibHeader.h"
  25. #include "Task.h"
  26.  
  27.  
  28.     /*
  29.      *        Static Routines
  30.      */
  31.  
  32. static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner);
  33. static void RemSegNode(struct muSegNode *snode);
  34. static struct muSegNode *FindSegNode(BPTR SegList);
  35. static struct muExtOwner *GetSegOwner(BPTR seglist);
  36.  
  37.  
  38.     /*
  39.      *        Allocate and Add a Segment Node
  40.      *
  41.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  42.      */
  43.  
  44. static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner)
  45. {
  46.     struct muSegNode *snode;
  47.  
  48.     if (snode = MAlloc(sizeof(struct muSegNode))) {
  49.         snode->SegList = seglist;
  50.         snode->Owner.uid = (owner & muMASK_UID)>>16;
  51.         snode->Owner.gid = owner & muMASK_GID;
  52.         AddHead((struct List *)&muBase->SegOwnerList, (struct Node *)&snode->Node);
  53.     }
  54.     return(snode);
  55. }
  56.  
  57.  
  58.     /*
  59.      *        Remove and Deallocate a Segment Node
  60.      *
  61.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  62.      */
  63.  
  64. static void __inline RemSegNode(struct muSegNode *snode)
  65. {
  66.     Remove((struct Node *)&snode->Node);
  67.     Free(snode, sizeof(struct muSegNode));
  68. }
  69.  
  70.  
  71.     /*
  72.      *        Find the Segment Node for a given SegList
  73.      *
  74.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  75.      */
  76.  
  77. static struct muSegNode *FindSegNode(BPTR seglist)
  78. {
  79.     struct MinNode *node;
  80.     struct muSegNode *snode;
  81.  
  82.     for (node = muBase->SegOwnerList.mlh_Head;
  83.           node->mln_Succ && ((snode = (struct muSegNode *)node)->SegList != seglist);
  84.           node = node->mln_Succ);
  85.     if (!node->mln_Succ)
  86.         snode = NULL;
  87.     return(snode);
  88. }
  89.  
  90.  
  91.     /*
  92.      *        Get the owner of a Segment
  93.      *
  94.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  95.      */
  96.  
  97. static struct muExtOwner *GetSegOwner(BPTR seglist)
  98. {
  99.     struct muExtOwner *owner = NULL;
  100.     struct muSegNode *snode;
  101.  
  102.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  103.     if (snode = FindSegNode(seglist))
  104.         owner = &snode->Owner;
  105.     ReleaseSemaphore(&muBase->SegOwnerSem);
  106.     return(owner);
  107. }
  108.  
  109.  
  110.     /*
  111.      *        Init Segment List
  112.      */
  113.  
  114. void InitSegList(void)
  115. {
  116.     ObtainSemaphore(&muBase->SegOwnerSem);
  117.     NewList((struct List *)&muBase->SegOwnerList);
  118.     ReleaseSemaphore(&muBase->SegOwnerSem);
  119. }
  120.  
  121.  
  122.     /*
  123.      *        Replacement for the dos.library LoadSeg() function
  124.      */
  125.  
  126. BPTR __asm __saveds NEWLoadSeg(register __d1 STRPTR name, register __a6 struct DosLibrary *dosbase)
  127. {
  128.     BPTR fl;
  129.     struct FileInfoBlock *fib;
  130.     ULONG owner = muOWNER_NOBODY;
  131.     BPTR seglist;
  132.  
  133.     if (name && (fl = Lock(name, ACCESS_READ))) {
  134.         if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
  135.              (fib = AllocDosObject(DOS_FIB, NULL))) {
  136.             if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  137.                 owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  138.             FreeDosObject(DOS_FIB, fib);
  139.         }
  140.         UnLock(fl);
  141.     }
  142.     seglist = muBase->OLDLoadSeg(name, dosbase);
  143.     if (owner & muMASK_UID) {
  144.         ObtainSemaphore(&muBase->SegOwnerSem);
  145.         AddSegNode(seglist, owner);
  146.         ReleaseSemaphore(&muBase->SegOwnerSem);
  147.     }
  148.     return(seglist);
  149. }
  150.  
  151.  
  152.     /*
  153.      *        Replacement for the dos.library NewLoadSeg() function
  154.      */
  155.  
  156. BPTR __asm __saveds NEWNewLoadSeg(register __d1 STRPTR name, register __d2 struct TagItem *tags,
  157.                                              register __a6 struct DosLibrary *dosbase)
  158. {
  159.     BPTR fl;
  160.     struct FileInfoBlock *fib;
  161.     ULONG owner = muOWNER_NOBODY;
  162.     BPTR seglist;
  163.  
  164.     if (name && (fl = Lock(name, ACCESS_READ))) {
  165.         if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
  166.              (fib = AllocDosObject(DOS_FIB, NULL))) {
  167.             if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  168.                 owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  169.             FreeDosObject(DOS_FIB, fib);
  170.         }
  171.         UnLock(fl);
  172.     }
  173.     seglist = muBase->OLDNewLoadSeg(name, tags, dosbase);
  174.     if (owner & muMASK_UID) {
  175.         ObtainSemaphore(&muBase->SegOwnerSem);
  176.         AddSegNode(seglist, owner);
  177.         ReleaseSemaphore(&muBase->SegOwnerSem);
  178.     }
  179.     return(seglist);
  180. }
  181.  
  182.  
  183.     /*
  184.      *        Replacement for the dos.library UnLoadSeg() function
  185.      */
  186.  
  187. BOOL __asm __saveds NEWUnLoadSeg(register __d1 BPTR seglist, register __a6 struct DosLibrary *dosbase)
  188. {
  189.     struct muSegNode *snode;
  190.  
  191.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  192.     if (snode = FindSegNode(seglist))
  193.         RemSegNode(snode);
  194.     ReleaseSemaphore(&muBase->SegOwnerSem);
  195.     return(muBase->OLDUnLoadSeg(seglist, dosbase));
  196. }
  197.  
  198.  
  199.     /*
  200.      *        Replacement for the dos.library InternalLoadSeg() function
  201.      */
  202.  
  203. BPTR __asm __saveds NEWInternalLoadSeg(register __d0 BPTR fh, register __a0 BPTR table,
  204.                                                     register __a1 LONG *functionarray, register __a2 LONG *stack,
  205.                                                     register __a6 struct DosLibrary *dosbase)
  206. {
  207.     struct FileInfoBlock *fib;
  208.     ULONG owner = muOWNER_NOBODY;
  209.     BPTR seglist;
  210.  
  211.     if (fh && CheckmuFSVolume(((struct FileHandle *)BADDR(fh))->fh_Type) &&
  212.          (fib = AllocDosObject(DOS_FIB, NULL))) {
  213.         if (ExamineFH(fh, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  214.             owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  215.         FreeDosObject(DOS_FIB, fib);
  216.     }
  217.     seglist = muBase->OLDInternalLoadSeg(fh, table, functionarray, stack, dosbase);
  218.     if (owner & muMASK_UID) {
  219.         ObtainSemaphore(&muBase->SegOwnerSem);
  220.         AddSegNode(seglist, owner);
  221.         ReleaseSemaphore(&muBase->SegOwnerSem);
  222.     }
  223.     return(seglist);
  224. }
  225.  
  226.  
  227.     /*
  228.      *        Replacement for the dos.library InternalUnLoadSeg() function
  229.      */
  230.  
  231. BOOL __asm __saveds NEWInternalUnLoadSeg(register __d1 BPTR seglist, register __a1 void (*freefunc)(),
  232.                                                       register __a6 struct DosLibrary *dosbase)
  233. {
  234.     struct muSegNode *snode;
  235.  
  236.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  237.     if (snode = FindSegNode(seglist))
  238.         RemSegNode(snode);
  239.     ReleaseSemaphore(&muBase->SegOwnerSem);
  240.  
  241.     return(muBase->OLDInternalUnLoadSeg(seglist, freefunc, dosbase));
  242. }
  243.  
  244.  
  245.     /*
  246.      *        Replacement for the dos.library CreateProc() function
  247.      */
  248.  
  249. struct Process __asm __saveds *NEWCreateProc(register __d1 STRPTR name, register __d2 LONG pri,
  250.                                                             register __d3 BPTR seglist, register __d4 LONG stacksize,
  251.                                                             register __a6 struct DosLibrary *dosbase)
  252. {
  253.     struct muExtOwner *owner;
  254.     struct Process *proc;
  255.  
  256.     if (owner = GetSegOwner(seglist))
  257.         PushTask(SysBase->ThisTask, owner);
  258.     proc = muBase->OLDCreateProc(name, pri, seglist, stacksize, dosbase);
  259.     if (owner)
  260.         PopTask(SysBase->ThisTask);
  261.     return(proc);
  262. }
  263.  
  264.  
  265.     /*
  266.      *        Replacement for the dos.library CreateNewProc() function
  267.      */
  268.  
  269. struct Process __asm __saveds *NEWCreateNewProc(register __d1 struct TagItem *tags,
  270.                                                                 register __a6 struct DosLibrary *dosbase)
  271. {
  272.     struct muExtOwner *owner = NULL;
  273.     struct Process *proc;
  274.     BPTR seglist;
  275.  
  276.     if (tags && (seglist = (BPTR)GetTagData(NP_Seglist, NULL, tags)) && (owner = GetSegOwner(seglist)))
  277.         PushTask(SysBase->ThisTask, owner);
  278.     proc = muBase->OLDCreateNewProc(tags, dosbase);
  279.     if (owner)
  280.         PopTask(SysBase->ThisTask);
  281.     return(proc);
  282. }
  283.  
  284.  
  285.     /*
  286.      *        Replacement for the dos.library RunCommand() function
  287.      */
  288.  
  289. LONG __asm __saveds NEWRunCommand(register __d1 BPTR seglist, register __d2 ULONG stacksize,
  290.                                              register __d3 STRPTR argptr, register __d4 ULONG argsize,
  291.                                              register __a6 struct DosLibrary *dosbase)
  292. {
  293.     struct muExtOwner *owner;
  294.     LONG rc;
  295.  
  296.     if (owner = GetSegOwner(seglist))
  297.         PushTask(SysBase->ThisTask, owner);
  298.     rc = muBase->OLDRunCommand(seglist, stacksize, argptr, argsize, dosbase);
  299.     if (owner)
  300.         PopTask(SysBase->ThisTask);
  301.     return(rc);
  302. }
  303.